package br.org.bertol.mestrado.util;

import java.io.File;
import java.lang.reflect.InvocationTargetException;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;

import br.org.bertol.mestrado.InputType;
import br.org.bertol.mestrado.Starter;
import br.org.bertol.mestrado.engine.optimisation.hillclimbing.Operador;
import br.org.bertol.mestrado.engine.optimisation.pso.TypeMovement;

public class Configurator {

	private final Configuration configuration;
	
	public Configurator(final String sourceFile) throws ConfigurationException {
		configuration = new PropertiesConfiguration(sourceFile);
	}

	public Configurator(final File sourceFile) throws ConfigurationException {
		configuration = new PropertiesConfiguration(sourceFile);
	}

	public Configurator() throws ConfigurationException {
		configuration = new PropertiesConfiguration("pratico.properties");
	}
	
	public int getIteracoes(){
		final int input = configuration.getInt("iteracoes");
		
		return input;
	}
	
	public float getInitialInertia(){
		final float input = configuration.getFloat("pso.initialinertia");
		
		return input;
	}
	
	public float getFinalInertia(){
		final float input = configuration.getFloat("pso.finalinertia");
		
		return input;
	}
	
	public float getFatorSocial(){
		final float input = configuration.getFloat("pso.social");
		
		return input;
	}
	
	public float getFatorCognitivo(){
		final float input = configuration.getFloat("pso.cognitivo");
		
		return input;
	}
	
	public String[] getSystems(){
		final String[] input = configuration.getStringArray("sistemas");
		
		if(input.length == 0)
			return input;
		
		final String[] systems = new String[input.length];
	
		for (int i = 0; i < input.length; i++) {
			systems[i] = input[i];
		}
		
		return systems;
	}
	
	public String getSourcePath(){
		final String input = configuration.getString("sourcepath");
		
		return input;
	}
	
	public String getOutPutFile(){
		final String input = configuration.getString("outputfile");
		
		return input;
	}
	
	public InputType[] getInputTypes(){
		final String[] input = configuration.getStringArray("entradas");
		
		if(input.length == 0)
			return InputType.values();
		
		final InputType[] inputTypes = new InputType[input.length];
	
		for (int i = 0; i < input.length; i++) {
			inputTypes[i] = InputType.valueOf(input[i]);
		}
		
		return inputTypes;
	}
	
	public TypeMovement[] getTypeMovements(){
		final String[] input = configuration.getStringArray("pso.movimentos");
		
		if(input.length == 0)
			return TypeMovement.values();
		
		final TypeMovement[] typeMovements = new TypeMovement[input.length];
	
		for (int i = 0; i < input.length; i++) {
			typeMovements[i] = TypeMovement.valueOf(input[i]);
		}
		
		return typeMovements;
	}
	
	public Operador[] getOperacao(){
		final String[] input = configuration.getStringArray("hillclimbing.operadores");
		
		if(input.length == 0)
			return Operador.values();
		
		final Operador[] operador = new Operador[input.length];
	
		for (int i = 0; i < input.length; i++) {
			operador[i] = Operador.valueOf(input[i]);
		}
		
		return operador;
	}
	
	public Starter<?>[] getEngineStarters() throws ClassNotFoundException, IllegalArgumentException, SecurityException, 
													InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
	{
		final String[] input = configuration.getStringArray("starters");
		
		if(input.length == 0)
			throw new ClassNotFoundException("Especificar engines a serem usadas.");
		
		final Starter<?>[] newInstances = new Starter<?>[input.length];
		
		for (int i = 0; i < input.length; i++) {
			Class<?> c = Class.forName(input[i]);
			
			newInstances[i] = (Starter<?>) c.getConstructor(Configurator.class).newInstance(this);
		}
		
		return newInstances;
	}
}
